home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
INFO
/
XFDISK.ZIP
/
PREPARE.A86
< prev
next >
Wrap
Text File
|
1991-08-28
|
36KB
|
859 lines
;==============================================================================
;
; PREPARE version 1.00 August 28, 1991
; Fixed Disk Preparation and Partitioning Software.
; Copyright (C) 1991 Dennis W. Person. All rights reserved.
;
;==============================================================================
;
; written by: Dennis W. Person
; 6828 Devonshire Drive
; Canton, MI 48187-2613
;
;==============================================================================
;
; This program will clear ALL sectors on a fixed disk by writing the value V to
; ALL sectors. You CANNOT recover any data on your fixed disk once it has been
; cleared. BEFORE running this program, make sure you have a current backup of
; your fixed disk.
;
; Command: PREPARE [/?│[/1│/2] [/R│/P] [/V:vvv] [/C:cccc] [/H:hhh] [/S:ss]]
;
; Options: /? display this help
; /1 prepare 1st fixed disk
; /2 prepare 2nd fixed disk
; /R read disk only (use to test disk)
; /P prepare fixed disk by writing V (default of 0) to all sectors
; /V specify decimal value [vvv] to use for preparing fixed disk
; /C specify maximum cylinder [cccc] (0..1023)
; /H specify maximum head [hhh] (0..255)
; /S specify maximum sectors per track [ss] (1..63)
;
; The options [/1│/2] and [/R│/P] must be specified to execute the command.
;==============================================================================
DOS_VER EQU 5 ; program intended for DOS 5.00 or greater
IBUFSIZE EQU 1 ; maximum number of character allowed in input buffer
VDECDIGS EQU 3 ; maximum number of decimal digits for value
CDECDIGS EQU 4 ; maximum number of decimal digits for cylinders
HDECDIGS EQU 3 ; maximum number of decimal digits for heads
SDECDIGS EQU 2 ; maximum number of decimal digits for sectors
MAX_VAL EQU 255 ; maximum value allowed for preparing disk
MAX_CYL EQU 1023 ; maximum cylinder number allowed by DOS
MAX_HDS EQU 255 ; maximum head number allowed by DOS
MAX_SEC EQU 63 ; maximum sector number allowed by DOS
BPS EQU 512 ; bytes per sector (default defined by DOS)
NONE EQU 0FFFFh ; define value to indicate no user selected disk parameter
BS EQU 08h ; ASCII backspace
CR EQU 0Dh ; ASCII carriage return
LF EQU 0Ah ; ASCII line feed
EOM EQU "$" ; ASCII character defining end of message
UPCHRMSK EQU 0DFh ; mask to convert lower case to upper case
DRIVE_1 EQU "1" ; drive character for 1st fixed disk drive
DRIVE_2 EQU "2" ; drive character for 2nd fixed disk drive
DRV_1_NO EQU 080h ; drive number for 1st fixed disk drive
DRV_2_NO EQU 081h ; drive number for 2nd fixed disk drive
RD_CODE EQU 02h ; disk service function code to read from disk drive
WR_CODE EQU 03h ; disk service function code to write to disk drive
CTRLBINT EQU 01Bh ; CTRL-BREAK INT number
CTRLCINT EQU 023h ; CTRL-C INT number
BUFFER EQU 080h ; address of command line buffer
;==============================================================================
ORG 0100h ; set beginning address for program
MAIN: MOV AX,CS ; initialize segment registers
MOV DS,AX ; except those related to the stack,
MOV ES,AX ; i.e., SS, and the stack pointer, SP
MOV DX,SIGNON ; display sign-on message
CALL PUTMSG
MOV AH,030h ; get function code and
INT 021h ; get DOS version number
CMP AL,DOS_VER ; check if DOS version appropriate
JGE CONTINUE ; continue if DOS version appropriate
; otherwise, . . .
MOV DX,DOSMSG ; get address of exit message
MOV AL,081h ; set exit error code
JMP EXIT
CONTINUE: CALL PARSE ; parse options on command line
JC SHOWHELP ; CF set if error occurred
CMP BYTE PTR [DRIVE_NO],DRV_1_NO ; check if user entered /1
JZ HAVEDRV ; otherwise user MUST enter /2
CMP BYTE PTR [DRIVE_NO],DRV_2_NO ; check if user entered /2
JZ HAVEDRV ; show HELP if no /1 or /2
SHOWHELP: MOV DX,HELPMSG ; get address of exit message
MOV AL,0FFh ; set exit error code
JMP EXIT
HAVEDRV: CALL GETPARAM ; get parameters for fixed disk drive selected by user
JNC CHK_VAL ; CF set if no fixed disk drive installed
MOV DX,NODRVMSG ; get address of exit message
MOV AL,082h ; set exit error code
JMP EXIT
CHK_VAL: MOV SI,USR_VAL ; get address of user specified value
MOV AX,[SI] ; get value specified by user and
CMP AX,MAX_VAL ; and check that value ok
JLE SET_CYL
; otherwise, . . .
MOV DX,BAD_VAL ; get address of exit message
MOV AL,088h ; set exit error code
JMP EXIT
SET_CYL: MOV BX,NONE ; prepare to check for user parameters
MOV SI,USR_CYL ; get address of user parameter for cylinders
CMP [SI],BX ; check if user entered value for cylinders
JZ SET_HDS ; if no value on command line
MOV AX,[SI] ; get value specified by user and
MOV [CYL_MAX],AX ; put in location for max. cylinders
CMP AX,MAX_CYL ; check if more than maximum allowed by DOS
JLE SET_HDS ; continue if value entered by user ok
; otherwise, . . .
MOV DX,BAD_CYL ; get address of exit message
MOV AL,085h ; set exit error code
JMP EXIT
SET_HDS: MOV SI,USR_HDS ; get address of user parameter for heads
CMP [SI],BX ; check if user entered value for heads
JZ SET_SEC ; if no value on command line
MOV AX,[SI] ; get value specified by user and
MOV [HDS_MAX],AX ; put in location for max. heads
CMP AX,MAX_HDS ; check if more than maximum allowed by DOS
JLE SET_SEC ; continue if value entered by user ok
; otherwise, . . .
MOV DX,BAD_HDS ; get address of exit message
MOV AL,086h ; set exit error code
JMP EXIT
SET_SEC: MOV SI,USR_SEC ; get address of user parameter for sectors
CMP [SI],BX ; check if user entered value for sectors
JZ WARNUSR ; if no value on command line
MOV AX,[SI] ; get value specified by user and
MOV [SECTORS],AX ; put in location for sectors per track
OR AX,0 ; check that user specfied at least 1 sector
JZ BAD_USR ; if zero, display error message
; otherwise, . . .
CMP AX,MAX_SEC ; check if more than maximum allowed by DOS
JLE WARNUSR ; continue if value entered by user ok
; otherwise, . . .
BAD_USR: MOV DX,BAD_SEC ; get address of exit message
MOV AL,087h ; set exit error code
JMP EXIT
WARNUSR: MOV DX,WARNMSG ; get address of write warning message
CMP BYTE PTR [RW_FUNC],WR_CODE ; check if going to clear disk
JZ SHOWSTAT ; and display write warning message
; otherwise, . . .
MOV DX,READMSG ; get address of read warning message
CMP BYTE PTR [RW_FUNC],RD_CODE ; check if going to read disk
JZ SHOWSTAT ; and display write warning message
; otherwise, . . .
MOV DX,BAD_CODE ; get address of exit message
MOV AL,083h ; get exit error code
JMP EXIT ; user MUST specify /R or /P
SHOWSTAT: CALL PUTMSG ; display warning regarding disk READ or WRITE
QUERYUSR: MOV DX,ASKYN ; get address of message and
CALL PROMPTER ; prompt for user"s response
JZ QUERYUSR ; if no response, prompt again
; otherwise, . . .
OR CL,0 ; if more than 1 character entered,
JNZ QUERYUSR ; go prompt user again
; otherwise, . . .
AND AL,UPCHRMSK ; mask response to upper case
; and check for valid response
CMP AL,"Y" ; check user"s response for Y
JZ BEGIN ; if Y, begin disk preparation
; otherwise, . . .
CMP AL,"N" ; check user"s response for N
JNZ QUERYUSR ; if not N, then prompt again
; otherwise, . . .
MOV DX,QUITMSG ; get address of exit message
MOV AL,084h ; set exit error code
JMP EXIT ; quit program
BEGIN: MOV DX,RETURN ; return cursor and
CALL PUTMSG ; move cursor down two lines
MOV AL,CTRLBINT ; get INT number for CONTROL-BREAK
MOV DI,CTRL_BRK ; get location to save old INT vector
CALL SETINT ; set CONTROL-BREAK interrupt vector
MOV AL,CTRLCINT ; get INT number for CONTROL-C
MOV DI,CTRL_C ; get location to save old INT vector
CALL SETINT ; set CONTROL-BREAK interrupt vector
MOV CX,02000h ; set parameters to turn cursor off
CALL CURSOR ; call DOS video service handler
FILL_DTA: MOV AX,BPS ; calculate number of bytes required for disk buffer
MUL BX ; by multiplying number of sectors by 512 bytes
MOV SI,AX ; save result in SI
MOV AX,CS ; use 64K above current code segment as buffer area
ADD AX,01000h ; addd 64K to current CS
MOV ES,AX ; ES used for disk buffer segment
MOV DI,USR_VAL ; get address of value for preparing fixed disk
MOV AL,[DI] ; prepare to clear disk buffer
; and . . .
FILL: ES: MOV [SI-1],AL ; go do it
DEC SI
JNZ FILL
MOV AH,0 ; start with disk system in reset condition
INT 013h
MOV BX,[CYL_MAX] ; start at maximum disk cylinder
NEXTCYL: MOV [CYLINDER],BX ; get next cylinder to prepare
MOV CL,CDECDIGS ; get number of decimal digits to display cylinder
MOV DI,CYL_NUM ; get location to put decimal digits
CALL BIN2DEC ; and insert current cylinder into message
MOV BX,[HDS_MAX] ; start at maximum disk head
NEXTHEAD: MOV [HEAD],BX ; get next head to prepare
MOV CL,HDECDIGS ; get number of decimal digits to display head
MOV DI,HD_NUM ; get location to put decimal digits
CALL BIN2DEC ; and insert current head into message
MOV DX,DISKMSG ; get address of message
CALL PUTMSG ; show user current head and cylinder
MOV SI,3 ; initialize number of tries for accessing disk
TRYAGAIN: CALL CLRKEY ; clear keyboard buffer
CMP BYTE PTR [STOP],1 ; check if user pressed BREAK
JNZ DODISK
MOV DX,BREAKMSG ; get address of exit message
MOV AL,1 ; set exit error code
JMP EXIT
; setup to registers to do disk function
DODISK: MOV DH,[HEAD] ; get current head
MOV DL,[DRIVE_NO] ; get drive number [80] or [81]
MOV CH,[CYLINDER] ; get low-order byte for cylinder
MOV CL,6 ; prepare to get upper 2-bits for cylinder
MOV AL,[CYLINDER+1] ; get high-order byte for cylinder
SHL AL,CL ; shift lower 2-bits of AL to upper 2-bits of AL
MOV CL,AL ; copy upper 2-bits to CL for proper setup
OR CL,1 ; start with first sector on track (lower 6-bits)
XOR BX,BX ; get address of disk buffer ES:BX
MOV AL,[SECTORS] ; get number of sector to prepare
MOV AH,[RW_FUNC] ; get READ or WRITE function code
INT 013h ; call BIOS routine to do disk function
JNC EXITLOOP ; CF clear if no error
; otherwise, . . .
MOV AH,0 ; get function code to reset disk system
INT 013h ; call BIOS routine to reset disk system
DEC SI ; decrement counter for number of tries
JNZ TRYAGAIN ; and try again if counter > 0
; otherwise, . . .
MOV DX,ERRMSG ; get address of exit message
MOV AL,3 ; set exit error code
JMP EXIT
EXITLOOP: MOV BX,[HEAD] ; get current head
DEC BX ; prepare to do next head
JGE NEXTHEAD ; and go do next head until complete
MOV BX,[CYLINDER] ; get current cylinder
DEC BX ; prepare to do next cylinder
JGE NEXTCYL ; and go do next cylinder until complete
MOV DX,DONEMSG ; get address of exit message
MOV AL,0 ; set exit error code to indicate sucess
EXIT: PUSH AX ; save exit error code
PUSH DX ; save address of exit message
CMP AL,080h ; check exit error code
JNC EXIT2 ; codes greater than 07F did not change BREAK vectors
MOV CX,0607h ; set scan line parameters for DOS cursor
CALL CURSOR ; restore DOS cursor
MOV AL,CTRLCINT ; get INT number for CONTROL-C
MOV SI,CTRL_C ; get location of old INT vector
CALL RESETINT ; reset CONTROL-C interrupt vector
MOV AL,CTRLBINT ; get INT number for CONTROL-BREAK
MOV SI,CTRL_BRK ; get location of old INT vector
CALL RESETINT ; reset CONTROL-BREAK interrupt vector
EXIT2: MOV AH,0 ; exit with disk system in reset condition
INT 013h
POP DX ; get address of exit message
CALL PUTMSG ; and display exit message for user
POP AX ; get exit error code
MOV AH,04Ch ; get function code to exit program
INT 021h ; exit program with return code
;------------------------------------------------------------------------------
; subroutine to clear keyboard buffer
;------------------------------------------------------------------------------
CLRKEY: MOV AH,1 ; get function code to check keyboard
INT 016h ; call BIOS routine to check keyboard
JZ NOKEY ; if no key pressed, exit
; otherwise, . . .
MOV AH,0 ; get function code to read keyboard buffer
INT 016h ; call DOS function to read keyboard buffer
NOKEY: RET
;------------------------------------------------------------------------------
; subroutine to reset INT number address
;
; on entry: AL contains INT number
; SI contains location of saved INT vector
;------------------------------------------------------------------------------
RESETINT: MOV DX,[SI] ; put INT vector in DS:DX
MOV DS,[SI+2]
MOV AH,025h ; get function code
INT 021h ; restore INT vector
MOV AX,CS
MOV DS,AX ; restore DS register
RET
;------------------------------------------------------------------------------
; subroutine to save vector for INT number and set new vector
;
; on entry: AL contains INT number
; DI contains location to save old INT vector
; DS:DX contains new INT vector
;------------------------------------------------------------------------------
SETINT: PUSH AX
MOV AH,035h ; set function code and interrupt number
INT 021h ; get interrupt vector for CONTROL-BREAK
MOV [DI],BX ; save interrupt vector ES:BX
MOV [DI+2],ES
MOV DX,BREAK ; get address of CONTROL-BREAK handler DS:DX
POP AX ; get INT number for CONTROL-BREAK
MOV AH,025h ; set function code
INT 021h ; set interrupt vector for CONTROL-BREAK
RET
;------------------------------------------------------------------------------
; subroutine to set cursor start and end scan lines
;
; on entry: CH contains start scan line
; CL contains end scan line
;------------------------------------------------------------------------------
CURSOR: MOV AH,1 ; select function
INT 010h ; call DOS video service handler
RET
;------------------------------------------------------------------------------
; subroutine to get parameters for fixed disk drive
;
; on exit: AX contains number of cylinders [0 .. 1023]
; BL contains number of sectors per track [0 ... 255]
; CL contains number of heads (sides) [0 .... 63]
; DL contains number of fixed disk drives [1 or 2]
;
; values of register are invalid if carry flag set
;
; CF flag set if no fixed disk drives
; clear if at least 1 fixed disk drive
;------------------------------------------------------------------------------
GETPARAM: MOV AH,8 ; get function code to check drive parameters
MOV DL,[DRIVE_NO] ; get drive number for fixed disk drive
INT 013h ; call BIOS routine to get drive parameters
JC NODRIVE ; CF set if no fixed disks installed
MOV AH,[DRIVE_NO] ; get drive selected by user
AND AH,1 ; mask to check if 2nd fixed disk selected
XOR AH,DL ; determine if 2nd fixed disk exists
JZ NODRIVE ; ZF set if no 2nd fixed disk installed
XOR BH,BH ; process fixed disk drive parameters
MOV AH,CL ; that were returned by the INT 013h call
MOV BL,CL ; as follows:
AND AH,0C0h ;
AND BL,03Fh ; DL number of drives
MOV CL,6 ; DH number of heads
SHR AH,CL ; CL lower order byte for cylinders
MOV AL,CH ; CH upper 2-bits: high order 2-bits for cylinder
XOR CX,CX ; CH lower 6-bits: sectors per track
MOV CL,DH ;
MOV [CYL_MAX],AX ; save fixed disk drive parameters
MOV [SECTORS],BX
MOV [HDS_MAX],CX
MOV [NUM_DRVS],DL
CLC ; clear CF if no errors with fixed disk drive selected by user
RET
NODRIVE: STC ; set CF if errors with fixed disk drive selected by user
RET
;------------------------------------------------------------------------------
; subroutine to display message for user
;
; on entry: DX contains address of message
;------------------------------------------------------------------------------
PUTMSG: MOV AH,9 ; get function code to display message
INT 021h ; call DOS routine to display message
RET
;------------------------------------------------------------------------------
; subroutine to convert decimal ASCII characters to 16-bit binary value
;
; on entry: CL contains count of characters in command buffer
; CH contains maximum number of characters to process
; SI contains address of decimal ASCII characters less 1
; DI contains address to put binary value
;
; on exit: AX contains binary value
; BH contains number of decimal characters in number
; CF flag clear if valid value
; set if error occured
;
; MUL instruction uses the DX register for the high order 16-bits of
; the 32-bit result, so do NOT use the DX register in this subroutine.
;------------------------------------------------------------------------------
DEC2BIN: XOR AX,AX ; initialize registers to be used
XOR BX,BX
MOV BP,10
CHKBUFF: OR CL,0 ; check for more characters in buffer
JZ CHKFOR1 ; exit appropriately if no more characters
; otherwise, . . .
INC SI ; increment pointer to character buffer
DEC CL ; decrement character count
MOV BL,[SI] ; and fetch character
CMP BL," " ; if character is a space,
JZ CHKFOR1 ; exit appropriately
;
CHKOPT: CMP BL,"/" ; if beginning of another option,
JZ RESETBUF ; exit appropriately
CHKDIG: CMP BL,"0" ; if character is less than "0"
JL BADDIGIT ; exit with error
; OR . . .
CMP BL,"9" ; if character is greater than "9"
JG BADDIGIT ; exit with error
; otherwise, . . .
MUL BP ; multiply current value by 10 to shift decimal value
AND BL,0Fh ; convert ASCII decimal to BCD value
ADD AL,BL ; and value to lower order byte of AX
ADC AH,0 ; and carry to high order byte of AX
INC BH ; increment counter for number of characters
DEC CH ; check if more characters allowed
JNZ CHKBUFF ; and go get the next one
; otherwise, . . .
D2BDONE: MOV [DI],AX ; save binary value
CLC ; clear CF to indicate valid value
RET
RESETBUF: INC CL ; beginning of another option "/", so
DEC SI ; restore buffer pointer and count
CHKFOR1: OR BH,0 ; check that at least 1 decimal digit was entered
JNZ D2BDONE ; and exit with valid value
; otherwise, . . .
BADDIGIT: STC ; set CF to indicate error
RET
;------------------------------------------------------------------------------
; subroutine to convert 16-binary value to decimal ASCII characters
;
; on entry: BX contains binary value
; CL contains number of decimal digits
; DI contains address to put decimal ASCII characters
;
; DIV instruction uses the DX register for the high order 16-bits of
; the 32-bit dividend, so initialize the DX register before dividing.
;------------------------------------------------------------------------------
BIN2DEC: MOV DL," "
MOV CH,CL
MOV SI,DI
INIDIGS: MOV [SI],DL
INC SI
DEC CH
JNZ INIDIGS
MOV BP,10
DEC SI
DEC CL
JZ ONESDIG
MOV AX,1
MOV CH,CL
SETDIG: MUL BP
DEC CH
JNZ SETDIG
NEXTDIG: MOV CH,-1
DIVBY10X: INC CH
SUB BX,AX
JNC DIVBY10X
ADD BX,AX
CALL DEC2ASC
XOR DX,DX
DIV BP
DEC CL
JNZ NEXTDIG
ONESDIG: MOV CH,BL
DEC2ASC: ADD CH,"0"
CMP CH,"0"
JNZ PUTDIGIT
MOV DL," "
CMP DL,[DI-1]
JNZ PUTDIGIT
CMP DI,SI
JZ PUTDIGIT
MOV CH,DL
DEC DI
DEC SI
PUTDIGIT: MOV [DI],CH
INC DI
RET
;------------------------------------------------------------------------------
; subroutine to prompt the user and pre-process the user"s input
;
; on entry: DX contains address of prompt to be displayed
;------------------------------------------------------------------------------
PROMPTER: CALL PUTMSG ; display prompt on console
;
MOV CL,IBUFSIZE+1 ; get maximum size of input buffer
MOV SI,USRIBUFF ; get address of user input buffer
MOV [SI],CL ; and put size into buffer
;
ADD SI,2 ; point to first charcter in buffer
; and . . .
FILLBUFR: MOV BYTE PTR [SI]," " ; put space into buffer
INC SI ; increment buffer pointer
DEC CL ; decrement buffer counter
JNZ FILLBUFR ; loop until end of buffer
;
MOV DX,USRIBUFF ; get address of buffer DS:DX
MOV AL,0Ah ; get function code to input string
MOV AH,0Ch ; get function code to clear keyboard buffer
INT 021h ; go execute DOS function to read keyboard
;
MOV SI,USRIBUFF+1 ; point to buffer count
MOV CL,[SI] ; get count for number of characters
GET1CHAR: OR CL,0 ; check if count is zero
JZ ENDPRMPT ; if no user response, return with Z set
; otherwise, . . .
DEC CL ; decrement buffer character count
INC SI ; point to next character in buffer
MOV AL,[SI] ; and retrieve character to AL
;
CMP AL," " ; check for space character
JZ GET1CHAR ; if space, check for another character
; otherwise, . . .
ENDPRMPT: RET ; return with character in AL
;------------------------------------------------------------------------------
; subroutine to process the command line options
;
; valid options: /? display command help
; /1 select 1st fixed disk
; /2 select 2nd fixed disk
; /P prepare fixed disk by writing 0 to all sectors
; /R read disk only {used for testing disk}
; /V:vvv specify decimal value [vvv] for preparing disk
; /C:cccc specify maximum cylinder [cccc]
; /H:hhh specify maximum head [hhh]
; /S:ss specify maximum sectors [ss]
;
; on exit: CF flag set if error on command line
; clear if no errors on command line
;
;------------------------------------------------------------------------------
PARSE: MOV SI,BUFFER ; get address of command buffer
MOV CL,[SI] ; get number of characters in buffer
NEXTCHAR: CALL GET1CHAR ; get character from buffer
JZ COMERR ; exit with CF set if no characters in buffer
CMP AL,"/" ; check for option prefix character
JNZ COMERR ; exit with CF set if character NOT "/"
CALL GET1CHAR ; get next next character from buffer
JZ COMERR ; exit with CF set if no characters in buffer
OPT0: CMP AL,"?" ; check if user is requesting HELP
JZ COMERR ; exit with CF set if user needs HELP
OPT1: CMP AL,DRIVE_1 ; check if user selected 1st fixed disk
JNZ OPT2
; and . . .
MOV AH,DRV_1_NO ; prepare to set drive number for 1st fixed disk
JMP SETDRIVE
OPT2: CMP AL,DRIVE_2 ; check if user selected 2nd fixed disk
JNZ OPT3
; and . . .
MOV AH,DRV_2_NO ; prepare to set drive number for 2nd fixed disk
SETDRIVE: MOV [WARN_DRV],AL ; put drive character into warning message
MOV [DONE_DRV],AL ; put drive character into completion message
MOV [DRIVE_NO],AH ; set drive number for fixed disk selected by user
JMP GETNEXT ; go continue to parse command line
OPT3: AND AL,UPCHRMSK ; convert lowercase to uppercase
CMP AL,"R" ; check if user selected READ option
JNZ OPT4
; and . . .
MOV AL,RD_CODE ; prepare to setup for disk READ
JMP SET_RW
OPT4: CMP AL,"P" ; check if user selected PREPARE option
JNZ OPT5
; and . . .
MOV AL,WR_CODE ; prepare to setup for disk WRITE
SET_RW: MOV [RW_FUNC],AL ; set function code to READ or WRITE disk
GETNEXT: OR CL,CL ; if more characters entered on command line
JNZ NEXTCHAR ; go process additional options entered by user
CLC ; exit with CF clear if no errors on command line
RET
COMERR: STC ; exit with CF set if errors on command line
RET
OPT5: MOV AH,AL ; prepare to check for additional options
CALL GET1CHAR ; get next character from buffer
JZ COMERR ; exit with CF set if no characters in buffer
CMP AX,"V:" ; check if user selecting value for preparing disk
JNZ OPT6
MOV CH,VDECDIGS ; get max. number of decimal digits for value
MOV DI,USR_VAL ; get location to put user value
JMP GETNUM ; continue processing to get binary value
OPT6: CMP AX,"C:" ; check if user selecting value to prepare disk
JNZ OPT7
MOV CH,CDECDIGS ; get max. number of decimal digits for cylinders
MOV DI,USR_CYL ; get location to put user number of cylinders
JMP GETNUM ; continue processing to get binary value
OPT7: CMP AX,"H:" ; check if user selecting number of heads
JNZ OPT8
MOV CH,HDECDIGS ; get max. number of decimal digits for heads
MOV DI,USR_HDS ; get location to put user number of heads
JMP GETNUM ; continue processing to get binary value
OPT8: CMP AX,"S:" ; check if user selecting number of sectors
JNZ COMERR ; exit if CF set if valid option NOT entered
MOV CH,SDECDIGS ; get max. number of decimal digits for sectors
MOV DI,USR_SEC ; get location to put user number of sectors
GETNUM: CALL DEC2BIN ; convert ASCII decimal number to binary value
JNC GETNEXT ; if no error, go parse additional options
; otherwise, . . .
RET ; exit with CF set if bad number
;------------------------------------------------------------------------------
; subroutine to handle CONTROL-BREAK and CONTROL-C
;------------------------------------------------------------------------------
BREAK: CS: MOV BYTE PTR [STOP],1 ; simply set STOP if user presses BREAK
IRET
;------------------------------------------------------------------------------
USRIBUFF: DB IBUFSIZE+3 DUP ? ; input buffer for user query
CTRL_C: DW 2 DUP ? ; address of CONTROL-C handler
CTRL_BRK: DW 2 DUP ? ; address of CONTROL-BREAK handler
STOP DB 0 ; set to 1 if user presses CONTROL-C or CONTROL-BREAK
HEAD DW ? ; counter for heads
CYLINDER DW ? ; counter for cylinders
CYL_MAX DW ? ; maximum number of cylinders MINUS 1
HDS_MAX DW ? ; maximum number of heads MINUS 1
SECTORS DW ? ; sectors per track
USR_VAL: DW 0 ; user selected value to use for preparing fixed disk
USR_CYL: DW NONE ; maximum cylinder number entered by user on command line
USR_HDS: DW NONE ; maximum head number entered by user on command line
USR_SEC: DW NONE ; sectors per track entered by user on command line
NUM_DRVS DB ? ; number of fixed disk drives
DRIVE_NO DB 0 ; fixed disk drive number
RW_FUNC DB 0 ; function code to read from or write to disk drive
DISKMSG: DB "Head: "
HD_NUM: DB HDECDIGS DUP ?
DB " "
DB "Cylinder: "
CYL_NUM: DB CDECDIGS DUP ?
DB CR
DB EOM
SIGNON: DB CR,LF
DB "PREPARE version 1.00 August 28, 1991",CR,LF
DB "Fixed Disk Preparation and Partitioning Software.",CR,LF
DB "Copyright (C) 1991 Dennis W. Person. All rights reserved.",CR,LF
DB EOM
READMSG: DB CR,LF
DB "Fixed disk will be READ for test purposes only.",CR,LF
DB EOM
WARNMSG: DB CR,LF
DB "═════════════════════ ═════════════════════"
DB CR,LF
DB " W A R N I N G ! ! ! W A R N I N G ! ! ! "
DB CR,LF
DB "═════════════════════ ═════════════════════"
DB CR,LF,LF
DB "ALL DATA ON FIXED DISK DRIVE ["
WARN_DRV DB ?
DB "] WILL BE LOST IF YOU CONTINUE.",CR,LF
DB EOM
ASKYN: DB CR,
DB "Proceed with fixed disk preparation [Y│N] ? ",BS
DB EOM
RETURN: DB CR,LF,LF,EOM
BAD_VAL: DB CR,LF
DB "ERROR [88]: Value used to prepare fixed disk must be less than 256.",CR,LF
DB EOM
BAD_SEC: DB CR,LF
DB "ERROR [87]: Number of sectors MUST be at least 1 but less than 64.",CR,LF
DB EOM
BAD_HDS: DB CR,LF
DB "ERROR [86]: Number of heads MUST be less than 256.",CR,LF
DB EOM
BAD_CYL: DB CR,LF
DB "ERROR [85]: Number of cylinders MUST be less than 1024.",CR,LF
DB EOM
QUITMSG: DB CR,LF,LF
DB "ERROR [84]: Fixed disk preparation cancelled.",CR,LF
DB EOM
BAD_CODE: DB CR,LF
DB "ERROR [83]: You MUST also use either /R or /P on the command line.",CR,LF
DB EOM
NODRVMSG: DB CR,LF
DB "ERROR [82]: No fixed disk drive exists.",CR,LF
DB EOM
DOSMSG: DB CR,LF
DB "ERROR [81]: Incorrect DOS version. DOS 5.00 or greater needed."
DB CR,LF
DB EOM
ERRMSG: DB CR,LF,LF
DB "ERROR [2]: Unable to complete fixed disk preparation.",CR,LF
DB " Either disk is bad in area shown above OR",CR,LF
DB " you entered an invalid drive parameter.",CR,LF
DB EOM
BREAKMSG: DB CR,LF,LF
DB "ERROR [1]: Fixed disk preparation cancelled by BREAK."
DB CR,LF
DB EOM
DONEMSG: DB CR,LF,LF
DB "Fixed disk preparation for DRIVE ["
DONE_DRV DB ?
DB "] completed sucessfully.",CR,LF
DB EOM
HELPMSG: DB CR,LF
DB "This program will clear ALL sectors on a fixed disk by writing the value V to",CR,LF
DB "ALL sectors. You CANNOT recover any data on your fixed disk once it has been",CR,LF
DB "cleared. BEFORE running this program, make sure you have a current backup of",CR,LF
DB "your fixed disk."
DB CR,LF,LF
DB "Command: PREPARE [/?│[/1│/2] [/R│/P] [/V:vvv] [/C:cccc] [/H:hhh] [/S:ss]]"
DB CR,LF,LF
DB "Options: /? display this help",CR,LF
DB " /1 prepare 1st fixed disk",CR,LF
DB " /2 prepare 2nd fixed disk",CR,LF
DB " /R read fixed disk only (use to test disk)",CR,LF
DB " /P prepare fixed disk by writing V (default of 0) to all sectors",CR,LF
DB " /V specify decimal value [vvv] to use for preparing fixed disk",CR,LF
DB " /C specify maximum cylinder [cccc] (0..1023)",CR,LF
DB " /H specify maximum head [hhh] (0..255)",CR,LF
DB " /S specify maximum sectors per track [ss] (1..63)"
DB CR,LF,LF
DB "The options [/1│/2] and [/R│/P] must be specified to execute the command.",CR,LF
DB EOM
;==============================================================================
;
; PREPARE version 1.00 August 28, 1991
; Fixed Disk Preparation and Partitioning Software.
; Copyright (C) 1991 Dennis W. Person. All rights reserved.
;
;==============================================================================